import java.util.Collection;
import java.util.GregorianCalendar;
import java.util.HashMap;

/**
 * Classe de gestion d'ouvrage.
 * @author IUT, refactoré par E. Ceret
 * @version 2.0
 */
public class Ouvrage extends Document {

	// ************************************************************************************************************
	// Constantes
	// ************************************************************************************************************

	private static final long serialVersionUID = 1L;
	
	// ************************************************************************************************************
	// Attributs
	// ************************************************************************************************************

	private String _isbn;
	private String _editeur;
	private GregorianCalendar _dateEdition;
	private int _derNumExemplaire; //num du dernier exemplaire.
	

	// Attributs d'Association
	private HashMap<Integer, Exemplaire> _exemplaires;
	
	// ************************************************************************************************************
	// Constructeur
	// ************************************************************************************************************

	/**
	 * Constructeur. 
	 * @param isbn			numero ISBN de l'ouvrage
	 * @param titre			titre de l'ouvrage
	 * @param auteur		auteur de l'ouvrage
	 * @param editeur		editeur de l'ouvrage
	 * @param dateEdition	date d'edition
	 */
	public Ouvrage(String isbn, String titre, String editeur, GregorianCalendar dateEdition) {
		super(titre);
		this.setIsbn(isbn);
		this.setEditeur(editeur);
		this.setDateEdition(dateEdition);
		this.setExemplaires(new HashMap<Integer, Exemplaire>());
		this.setDerNumExemplaire(0);
		
	}

	// ************************************************************************************************************
	// Méthodes privées
	// ************************************************************************************************************
	
	//affecteurs
	
	public void setDateEdition(GregorianCalendar date){ _dateEdition = date; }
	public void setEditeur(String editeur){ _editeur = editeur; }
	public void setExemplaires(HashMap<Integer, Exemplaire> exemplaires) { _exemplaires = exemplaires; }
	public void setIsbn(String isbn) { this._isbn = isbn; }
	
    /** setter du num du dernier exemplaire
     *  @param derNumExemplaire nombre à affecter au dernier numéro d'exemplaire */
	private void setDerNumExemplaire(int derNumExemplaire) { _derNumExemplaire  = derNumExemplaire ; }
	
	//accesseurs
	private int getDerNumExemplaire() { return _derNumExemplaire; }
	
	// ------------------------------------------------------------------------------------------------------------
	// Traitements

	public void notifierObservateurs() {
		this.setChanged();
		this.notifyObservers();	
	}
	
	private void setExemplaire(int numero, Exemplaire exemplaire) {	_exemplaires.put(numero, exemplaire); }

	private int genererNumeroExemplaire() {
		this.setDerNumExemplaire(this.getDerNumExemplaire() + 1);
		return this.getDerNumExemplaire();
	} 

	// ************************************************************************************************************
	// Méthodes publiques
	// ************************************************************************************************************

	// ------------------------------------------------------------------------------------------------------------
	// Accesseurs
	
	public String getIsbn() { return _isbn; }
	
	public String getEditeur() { return _editeur; }
	
	public GregorianCalendar getDateEdition() { return _dateEdition; }
	
	public Exemplaire getExemplaire(int numero) { return (Exemplaire) _exemplaires.get(numero); }
	
	public Collection<Exemplaire> getExemplaires() { return _exemplaires.values(); }

	public int getNbExemplaires() { return _exemplaires.size(); }
	
	public String afficher() {
		String o = "ouvrage : " + this.getTitre() + "(" + this.getIsbn() + ")" + "\n\n" + "editeur : " + this.getEditeur() + "\n\n" + "date d'edition : " + this.getDateEdition();
		
		return o;
	}

	// ------------------------------------------------------------------------------------------------------------
	// Traitements

	/**
	 * Ajout d'un exemplaire à l'ouvrage. Le numéro de cet exemplaire est généré automatiquement pour l'ouvrage.
	 * @param dateReception date à laquelle l'exemplaire a été reçu.
	 * @return l'exemplaire ou null si la date de reception est antérieure à la date d'édition de l'ouvrage 
	 */
	public Exemplaire ajouterExemplaire(GregorianCalendar dateReception, int stat) {
		// Generation du numero chronologique de l'exemplaire
		int numero = this.genererNumeroExemplaire();
		if (this.verifDate(dateReception)){
		// Creation de l'exemplaire
			Exemplaire exemplaire = new Exemplaire(numero, dateReception, stat, this);
		// liaison de l'ouvrage a l'exemplaire
			this.setExemplaire(numero, exemplaire);
		// notifie ses observateurs du changement
			this.notifierObservateurs();
			return exemplaire;
		}
		else {
			return null;
		}
	} // Fin ajouterExemplaire

	/**
	 * @param dateRecep
	 * @return vrai si date réception de l'exemplaire est postérieure à la date édition de l'ouvrage
	 */
	private boolean verifDate(GregorianCalendar dateRecep) {
		return (dateRecep.after(_dateEdition));
	}
	
	public int getNbExemplairesEnConsultation(){
		int nb = 0;
		for (Exemplaire ex : this.getExemplaires() ){
			if (ex.estEnConsultation()) {
				nb = nb + 1;
			}
		}
		return nb;
	}
	
	public int getNbExemplairesEmpruntable(){
		int nb = 0;
		for (Exemplaire ex : this.getExemplaires() ){
			if (ex.estEmpruntable()) {
				nb = nb + 1;
			}
		}
		return nb;
	}
	
} // Fin Classe Ouvrage
